package com.zmx.piglearn.adapter

import android.content.Context
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.TextView

abstract class MyAdapter<T> (
    private val layoutRes: Int,
    private val dataset: MutableList<T>
): BaseAdapter() {

    class ViewHolder(context: Context, parent: ViewGroup, layoutRes: Int) {
        private val children = SparseArray<View>()
        private var item: View = LayoutInflater.from(context).inflate(layoutRes, parent, false)
        private var index: Int = 0

        init {
            item.tag = this
        }

        @SuppressWarnings("unchecked")
        private fun <T : View> getView(id: Int): T {
            var t = children.get(id) as T?
            if (t == null) {
                t = item.findViewById<View>(id) as T
                children.put(id, t)
            }
            return t
        }

        fun getItem () = item
        fun getIndex () = index

        fun setText (id: Int, text: CharSequence): ViewHolder {
            val view: View = getView(id)
            if (view is TextView) {
                view.text = text
            }
            return this
        }

        fun setImageResource (id: Int, drawableRes: Int): ViewHolder {
            val view: View = getView(id)
            if (view is ImageView) {
                view.setImageResource(drawableRes)
            } else {
                view.setBackgroundResource(drawableRes)
            }
            return this
        }

        fun setOnClickListener (id: Int, listener: View.OnClickListener): ViewHolder {
            val view: View = getView(id)
            view.setOnClickListener(listener)
            return this
        }

        fun setVisibility (id: Int, visible: Int): ViewHolder {
            val view: View = getView(id)
            view.visibility = visible
            return this
        }

        fun getTag (id: Int, obj: Any): ViewHolder {
            val view: View = getView(id)
            view.tag = obj
            return this
        }

        companion object {
            fun bind(
                context: Context,
                convertView: View?,
                parent: ViewGroup,
                layoutRes: Int,
                index: Int
            ): ViewHolder {
                val holder: ViewHolder
                if (convertView == null) {
                    holder = ViewHolder(context, parent, layoutRes)
                } else {
                    holder = convertView.tag as ViewHolder
                    holder.item = convertView
                }
                holder.index = index
                return holder
            }
        }
    }

    override fun getCount() = dataset.size

    override fun getItem(index: Int) = dataset[index]

    override fun getItemId(index: Int) = index.toLong()

    override fun getView(index: Int, convertView: View?, parent: ViewGroup?): View {
        val holder: ViewHolder = ViewHolder.bind(parent?.context!!, convertView, parent, layoutRes, index)
        val view: T? = getItem(index)
        if (view != null) {
            bindView(holder, view)
        }
        return holder.getItem()
    }

    abstract fun bindView (holder: ViewHolder, obj: T)

    fun add (data: T) {
        dataset.add(data)
        notifyDataSetChanged()
    }

    fun add (index: Int, data: T) {
        dataset.add(index, data)
        notifyDataSetChanged()
    }

    fun remove (data: T) {
        dataset.remove(data)
        notifyDataSetChanged()
    }

    fun removeAt (index: Int) {
        dataset.removeAt(index)
        notifyDataSetChanged()
    }

    fun clear () {
        dataset.clear()
        notifyDataSetChanged()
    }
}